#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <unordered_map>
#include <thread>
#include "logger.hpp"
namespace xchat
{
//定义sever类型
typedef websocketpp::server<websocketpp::config::asio> server_t;
//连接类型: server_t::connection_ptr
class Connection
{
public:
    struct Client
    {
        Client(const std::string &u, const std::string &ss)
            : uid(u), ssid(ss){}
        std::string uid;
        std::string ssid;
    };
    using ptr = std::shared_ptr<Connection>;
    Connection(){}
    ~Connection(){}
    //一个用户登录后，将用户id和长连接绑定
    void insert(const server_t::connection_ptr &conn, const std::string &uid, const std::string &ssid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _uid_connnections.insert(std::make_pair(uid, conn));
        _conn_client.insert(std::make_pair(conn, Client(uid, ssid)));
        LOG_DEBUG("新增长连接用户信息 {} {}", uid, ssid);
    }
    //通过用户ID 获取这个用户对应的长连接
    server_t::connection_ptr get_connection(const std::string &uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _uid_connnections.find(uid);
        if (it == _uid_connnections.end())
        {
            LOG_ERROR("未找到用户对应长连接{}", uid);
            return server_t::connection_ptr();
        }
        LOG_DEBUG("找到用户对应长连接{}", uid);
        return it->second;
    }
    //通过长连接 获取用户的uid 和 ssid
    bool get_client(const server_t::connection_ptr &conn, std::string &uid, std::string &ssid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conn_client.find(conn);
        if (it == _conn_client.end())
        {
            LOG_ERROR("获取-未找到长连接对应的客户端信息{}", size_t(conn.get()));
            return false;
        }
        uid = it->second.uid;
        ssid = it->second.ssid;
        LOG_DEBUG("获取用户客户端信息成功");
        return true;
    }
    //用户下线
    bool remove(const server_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conn_client.find(conn);
        if (it == _conn_client.end())
        {
            LOG_ERROR("删除-未找到长连接对应的客户端信息{}", size_t(conn.get()));
            return false;
        }
        _uid_connnections.erase(it->second.uid);
        _conn_client.erase(it);
        LOG_DEBUG("删除长连接对应的客户端信息 用户下线成功{}");
        return true;
    }
private:
    std::mutex _mutex;
    std::unordered_map<std::string, server_t::connection_ptr> _uid_connnections;    //用户id和长连接的映射
    std::unordered_map<server_t::connection_ptr, Client> _conn_client;            //长连接和用户信息的映射
};

}